package com.seckill.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.seckill.api.dto.item.ItemSearchDTO;
import com.seckill.api.dto.item.ItemSimpleInfoDTO;
import com.seckill.common.autoconfigure.mq.RabbitMqHelper;
import com.seckill.common.constants.ErrorInfo;
import com.seckill.common.constants.MqConstants;
import com.seckill.common.exceptions.BizIllegalException;
import com.seckill.common.utils.BeanUtils;
import com.seckill.common.utils.CollUtils;
import com.seckill.common.utils.UserContext;
import com.seckill.item.constants.ItemErrorInfo;
import com.seckill.item.constants.ItemStatus;
import com.seckill.item.constants.RedisContants;
import com.seckill.item.domian.dto.ItemDTO;
import com.seckill.item.domian.dto.OrderDetailDTO;
import com.seckill.item.domian.po.Category3PO;
import com.seckill.item.domian.po.Item;
import com.seckill.item.mapper.ItemMapper;
import com.seckill.item.service.IItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author zsc
 * @since 2025-05-17
 */
@Service
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements IItemService {

    @Autowired
    private RabbitMqHelper rabbitMqHelper;


    @Override
    @Cacheable(cacheNames = RedisContants.Formatter.STATISTICS_ITEM_NUM_CATE)
    public Map<Long, Integer> countItemNumOfCategory() {
        //1.查询条件
        LambdaQueryWrapper<Item> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Item::getStatus,
                Arrays.asList(ItemStatus.SHELF.getStatus(), ItemStatus.NO_UP_SHELF.getStatus(), ItemStatus.DOWN_SHELF.getStatus()));
        //2.查询数据
        List<Item> items = baseMapper.selectList(queryWrapper);
        Map<Long, Integer> cateIdAndNumMap = new HashMap<>();
        //3.统计每个分类的商品数量
        for (Item item : items) {
            //3.1一级分类数量
            Integer firstCateNum = cateIdAndNumMap.get(item.getFirstCateId());
            cateIdAndNumMap.put(item.getFirstCateId(), firstCateNum == null ? 1 : firstCateNum + 1);
            //3.2二级分类数量
            Integer secondCateNum = cateIdAndNumMap.get(item.getSecondCateId());
            cateIdAndNumMap.put(item.getSecondCateId(), secondCateNum == null ? 1 : secondCateNum + 1);
            //3.3三级分类数量够
            Integer thirdCateNum = cateIdAndNumMap.get(item.getThirdCateId());
            cateIdAndNumMap.put(item.getThirdCateId(), thirdCateNum == null ? 1 : thirdCateNum + 1);
        }
        return cateIdAndNumMap;
    }

    @Override
    public Integer countItemNumOfCategory(Long categoryId) {
        //1.商品统计条件
        LambdaQueryWrapper<Item> queryWrapper =
                Wrappers.lambdaQuery(Item.class)
                        .or().eq(Item::getFirstCateId, categoryId)
                        .or().eq(Item::getSecondCateId, categoryId)
                        .or().eq(Item::getThirdCateId, categoryId);
        //2.统计商品数量
        return Math.toIntExact(baseMapper.selectCount(queryWrapper));
    }

    @Override
    public List<Item> queryByCategoryIdAndLevel(Long categoryId, Integer level) {
        //1.商品基本信息查询条件
        LambdaQueryWrapper<Item> queryWrapper =
                Wrappers.lambdaQuery(Item.class)
                        .eq(level == 1, Item::getFirstCateId, categoryId) //一级商品分类
                        .eq(level == 2, Item::getSecondCateId, categoryId) //二级商品分类
                        .eq(level == 3, Item::getThirdCateId, categoryId);//三级商品分类
        //2.查询商品基本信息
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    @Cacheable(cacheNames = RedisContants.Formatter.CATEGORY_ID_LIST_HAVE_ITEM)
    public List<Long> getCategoryIdListWithItem() {
        // 1.查询条件
        List<Category3PO> category3s = baseMapper.queryCategoryIdWithItem();
        // 1.1.判空
        if(CollUtils.isEmpty(category3s)) {
            return new ArrayList<>();
        }
        // 2.将商品分类id设置到categoryIdList
        List<Long> categoryIdList = new ArrayList<>();
        category3s.stream().forEach(category3->{
            category3.setId(categoryIdList);
        });
        // 2.1.去重，并返回数据
        return categoryIdList.stream()
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public void downShelf(Long id) {
        //1.查询商品信息
        Item item = baseMapper.selectById(id);
        //1.1商品状态判断
        if(item == null || item.getStatus().equals(ItemStatus.DOWN_SHELF.getStatus())){
            throw new BizIllegalException(ItemErrorInfo.Msg.ITEM_DOWN_SHELF_FAILD);
        }
        //2.修改商品状态
        item.setStatus(ItemStatus.DOWN_SHELF.getStatus());
        baseMapper.updateById(item);
        //3.下架mq消息
        rabbitMqHelper.send(MqConstants.Exchange.ITEM_EXCHANGE, MqConstants.Key.ITEM_DOWN_KEY, id);
    }

    @Override
    public void add(ItemDTO itemDTO) {
        Item item = BeanUtils.copyBean(itemDTO, Item.class);
        //默认状态为未上架
        item.setStatus(ItemStatus.NO_UP_SHELF.getStatus());
        //销量为0
        item.setSold(0);
        //新建人
        item.setCreater(UserContext.getUser());
        //新增
        baseMapper.insert(item);
    }

    @Override
    public void update(ItemDTO itemDTO) {
        //1.查询商品信息
        Item item = baseMapper.selectById(itemDTO.getId());
        if(item == null){
            throw new BizIllegalException(ItemErrorInfo.Msg.ITEM_NOT_EXIST);
        }
        if(!item.getStatus().equals(ItemStatus.DOWN_SHELF.getStatus())){
            throw new BizIllegalException(ItemErrorInfo.Msg.ITEM_UPDATE_NOT_DOWN_SHELF);
        }
        item = BeanUtils.copyBean(itemDTO, Item.class);
        item.setUpdater(UserContext.getUser());
        baseMapper.updateById(item);
    }

    @Override
    public void delete(Long id) {
        //1.查询商品信息
        Item item = baseMapper.selectById(id);
        if(item == null){
            return;
        }
        if(!item.getStatus().equals(ItemStatus.DOWN_SHELF.getStatus())){
            throw new BizIllegalException(ItemErrorInfo.Msg.ITEM_DELETE_NOT_DOWN_SHELF);
        }
        baseMapper.deleteById(id);
    }

    @Override
    public void upShelf(Long id) {
        //1.查询商品信息
        Item item = baseMapper.selectById(id);
        if(item == null || item.getStatus().equals(ItemStatus.SHELF.getStatus())){
            return;
        }
        item.setStatus(ItemStatus.SHELF.getStatus());
        baseMapper.updateById(item);
        //2.上架mq消息
        rabbitMqHelper.send(MqConstants.Exchange.ITEM_EXCHANGE, MqConstants.Key.ITEM_DOWN_KEY, id);
    }

    @Override
    public void deductStock(OrderDetailDTO orderDetailDTO) {
        //1.查询商品信息
        Item item = baseMapper.selectById(orderDetailDTO.getItemId());
        //2.判断商品库存是否足够
        if(item.getStock() < orderDetailDTO.getNum()){
            throw new BizIllegalException(ItemErrorInfo.Msg.STOCK_NOT_ENOUGH);
        }
        //3.商品库存扣减
        item.setStock(item.getStock() - orderDetailDTO.getNum());
        baseMapper.updateById(item);
    }

    @Override
    public ItemSearchDTO getSearchInfo(Long id) {
        //1.查询商品信息
        Item item = baseMapper.selectById(id);
        if(item == null){
            return null;
        }
        //2.数据转换
        ItemSearchDTO itemSearchDTO = BeanUtils.copyBean(item, ItemSearchDTO.class);
        return itemSearchDTO;
    }

    @Override
    public List<ItemSimpleInfoDTO> getSimpleInfoList(List<Long> ids) {
       // 1.查询条件
        LambdaQueryWrapper<Item> queryWrapper =
                Wrappers.lambdaQuery(Item.class)
                        .in(Item::getId, ids);
        // 2.查询商品信息
        List<Item> items = baseMapper.selectList(queryWrapper);
        return items.stream()
                .map(item -> BeanUtils.copyBean(item, ItemSimpleInfoDTO.class))
                .collect(Collectors.toList());
    }
}
